package com.app.web.base.service;

import java.util.List;

import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TransactionRequiredException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.app.web.base.model.IdModel;

/**
 * Project: web<br>
 * Description: 基本业务逻辑Service层代码封装<br>
 * Copyright (c) 2012<br>
 * All Rights Reserved.<br>
 * @author <a href="mailto:gly420@163.com">GuanLuYong</a><br>
 */
public abstract class BaseService<T extends IdModel> {
	@PersistenceContext	protected EntityManager em;
	protected Logger log = LoggerFactory.getLogger(getClass());
	
	/**
	 * 分布查询，获取总数量
	 */
	protected ThreadLocal<Long> totalSize = new ThreadLocal<Long>();
	/**
	 * 查询实体对象列表
	 * @param prefix	查询sql语句前缀
	 * @param ttPrefix	查询总数量sql语句前缀
	 * @param suffix	查询sql语句后缀
	 * @param first		查询语句开始索引值
	 * @param pageSize	分页查询，每页显示数量
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> search(String prefix, String ttPrefix, String suffix, String orderby, int first, int pageSize) {
		String ttSql = ttPrefix + " " + suffix;
		log.debug(ttSql);
		Query q = em.createQuery(ttSql);
		totalSize.set((Long) q.getResultList().get(0));
		String sql = prefix + " " + suffix + " " + orderby;
		log.debug(sql);
		q = em.createQuery(sql);
		return q.setMaxResults(pageSize).setFirstResult(first).getResultList();
	}
	/**
	 * @function 更新实体
	 * @param super IdEntity
	 * @throws Exception
	 */
	public void update(T t) throws Exception {
		try {
			em.merge(t);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}
	/**
	 * @function 新增实体
	 * @param super IdEntity
	 * @throws Exception
	 */
	public void insert(T t) throws Exception {
		try {
			em.persist(t);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * @function 删除实体。
	 * 注：通常我们不调用此方法，只做业务上的删除，而非物理记录删除
	 * @param super IdEntity
	 * @throws Exception
	 */
	public void delete(T t) throws Exception {
		try {
			em.remove(t);
		} catch (Exception e) {
			e.printStackTrace();
			throw checkPersistException(e);
		}
	}
	/**
	 * @function 检查抛出的异常，并给出友好的提示信息，并返回此异常
	 * @param e
	 * @return
	 */
	protected Exception checkPersistException(Exception e) {
		if(e instanceof EntityExistsException) {
			return new Exception("已经存在一个实体管理器");
		} else if(e instanceof IllegalArgumentException) {
			return new Exception("对象不是一个有效的实体");
		} else if(e instanceof TransactionRequiredException) {
			return new Exception("没有启动一个事务");
		}
		return new Exception("数据持久化异常，请联系系统管理员.");
	}
	
	// Getter & Setter[em]
	public EntityManager getEm() {
		return em;
	}

	public void setEm(EntityManager em) {
		this.em = em;
	}

	public ThreadLocal<Long> getTotalSize() {
		return totalSize;
	}

	public void setTotalSize(ThreadLocal<Long> totalSize) {
		this.totalSize = totalSize;
	}
}
